package com.kun.companion.core.thread;

import org.jetbrains.annotations.NotNull;

import java.util.concurrent.*;

/**
 * 优先级线程池执行器
 *
 * <p>扩展自标准线程池执行器，提供以下增强功能：
 * <ul>
 *   <li>支持优先级任务队列（基于PriorityBlockingQueue）</li>
 *   <li>强制任务类型检查（仅接受PrioritizedTask类型任务）</li>
 *   <li>自定义FutureTask包装（PriorityFutureTask）</li>
 * </ul>
 *
 * <p>设计要点：
 * <ul>
 *   <li>通过继承体系保持与标准ThreadPoolExecutor的兼容性</li>
 *   <li>重写任务包装逻辑确保优先级比较生效</li>
 *   <li>强制类型约束保证队列比较器正常工作</li>
 * </ul>
 *
 * @author gzc
 * @since 2025/2/3
 */
public class PriorityThreadPoolExecutor extends ThreadPoolExecutor {

    /**
     * 构造优先级线程池
     *
     * @param corePoolSize      核心线程数（保持活跃的最小线程数）
     * @param maxPoolSize       最大线程数（队列满时创建的最大线程数）
     * @param keepAliveTime     空闲线程存活时间（单位由unit参数决定）
     * @param unit              时间单位（TimeUnit枚举）
     * @param workQueue         任务队列（必须为PriorityBlockingQueue类型）
     * @param taskThreadFactory 线程工厂（用于创建带有自定义名称/优先级的线程）
     * @throws IllegalArgumentException 如果workQueue不是PriorityBlockingQueue实例
     */
    public PriorityThreadPoolExecutor(int corePoolSize,
                                      int maxPoolSize,
                                      long keepAliveTime,
                                      @NotNull TimeUnit unit,
                                      @NotNull PriorityBlockingQueue<Runnable> workQueue,
                                      @NotNull ThreadFactory taskThreadFactory) {
        this(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue, taskThreadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
    }

    public PriorityThreadPoolExecutor(int corePoolSize,
                                      int maxPoolSize,
                                      long keepAliveTime,
                                      @NotNull TimeUnit unit,
                                      @NotNull PriorityBlockingQueue<Runnable> workQueue,
                                      @NotNull ThreadFactory taskThreadFactory,
                                      RejectedExecutionHandler rejectedExecutionHandler) {
        super(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue, taskThreadFactory, rejectedExecutionHandler);
        validateQueueType(workQueue);
    }

    /**
     * 验证队列类型（内部方法）
     */
    private void validateQueueType(BlockingQueue<Runnable> queue) {
        if (!(queue instanceof PriorityBlockingQueue)) {
            throw new IllegalArgumentException(
                    "必须使用PriorityBlockingQueue作为工作队列，当前类型：" + queue.getClass().getSimpleName());
        }
    }

    /**
     * 创建带优先级的FutureTask包装器
     *
     * <p>重写父类方法以返回自定义的PriorityFutureTask，
     * 这是实现优先级调度的关键步骤
     *
     * @param runnable 待执行任务（实际应为PrioritizedTask类型）
     * @param value    任务结果值（因任务为Runnable类型，通常为null）
     * @return 包装后的可执行FutureTask
     */
    @Override
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        // 确保任务类型正确性
        if (!(runnable instanceof PrioritizedTask)) {
            throw new IllegalStateException("非法的任务类型: " + runnable.getClass().getName());
        }
        return new PriorityFutureTask<>(runnable, value);
    }

    /**
     * 提交任务到线程池（类型安全版本）
     *
     * @param runnable 必须为PrioritizedTask类型实例
     * @return 任务执行结果Future
     * @throws IllegalArgumentException 如果任务类型不符合要求
     */
    @Override
    public Future<?> submit(@NotNull Runnable runnable) {
        validateTaskType(runnable);
        return super.submit(runnable);
    }

    /**
     * 验证任务类型（内部方法）
     */
    private void validateTaskType(Runnable task) {
        if (!(task instanceof PrioritizedTask)) {
            throw new IllegalArgumentException(
                    "仅支持PrioritizedTask类型任务，当前类型：" + task.getClass().getSimpleName());
        }
    }
}